package com.wuyan.web.base.api;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wuyan.helper.kit.DateHelper;
import com.wuyan.web.base.aop.ApiLogAnnotation;

import com.wuyan.web.base.entity.PubAccount;
import com.wuyan.web.base.entity.PubMsg;
import com.wuyan.web.base.form.PubMsgForm;
import com.wuyan.web.base.helper.BaseApi;
import com.wuyan.web.base.helper.auth.LoginInfo;
import com.wuyan.web.base.helper.rep.RepBody;
import com.wuyan.web.base.helper.rep.RepCodeEnum;
import com.wuyan.web.base.helper.rep.RepHelper;

import com.wuyan.web.base.helper.rep.RepPageData;
import com.wuyan.web.base.helper.req.CustomQueryParams;
import com.wuyan.web.base.repo.PubAccountExtendRepo;
import com.wuyan.web.base.repo.PubAccountRepo;
import com.wuyan.web.base.repo.PubMsgExtendRepo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * 扩展接口
 */

@Slf4j
@RestController
@RequestMapping("/api/pub-msg")
public class PubMsgApiExtend extends BaseApi implements RepHelper {

    @Autowired
    private PubAccountExtendRepo pubAccountRepo;

    @Autowired
    private PubMsgExtendRepo pubMsgExtendRepo;

    @Autowired
    private PubMsgApi pubMsgApi;

    @Autowired
    private ObjectMapper mapper;

    /**
     * 标记已读
     *
     * @param ids 主键
     * @return RepBody<Integer>
     */
    @GetMapping("/{ids}/read")
    @ApiLogAnnotation(name = "PubMsg:read")
    @Transactional(rollbackFor = Exception.class)
    public RepBody<Integer> read(@PathVariable("ids") Integer[] ids) {
        int row = pubMsgExtendRepo.read(Arrays.asList(ids), LocalDateTime.now());
        return ok(row);
    }

    /**
     * 标记所有未读消息为已读
     *
     * @return RepBody<Integer>
     */
    @GetMapping("/read-all")
    @ApiLogAnnotation(name = "PubMsg:readAll")
    @Transactional(rollbackFor = Exception.class)
    public RepBody<Integer> readAll(HttpServletRequest request) {
        LoginInfo loginInfo = getLoginInfo(request);
        int row = pubMsgExtendRepo.readAll(loginInfo.getAccount().getId(), LocalDateTime.now());
        return ok(row);
    }

    /**
     * 获取当前账户的消息
     *
     * @return RepBody<Integer>
     */
    @GetMapping("/own")
    @ApiLogAnnotation(name = "PubMsg:ownPage")
    public RepBody<RepPageData<PubMsg>> ownPage(HttpServletRequest request,
                                                @RequestParam(value = "isPage", required = false, defaultValue = "true") Boolean isPage,
                                                @RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
                                                @RequestParam(value = "limit", required = false, defaultValue = "15") Integer limit,
                                                @RequestParam(value = "params", required = false, defaultValue = "[]") String params,
                                                @RequestParam(value = "orders", required = false, defaultValue = "[]") String ordersParams)
            throws JsonProcessingException {
        LoginInfo loginInfo = getLoginInfo(request);

        // 查询参数
        List<CustomQueryParams> paramsList = mapper.readValue(params, new TypeReference<List<CustomQueryParams>>() {
        });
        paramsList.add(CustomQueryParams.builder()
                .left("recvUserId")
                .op("eq")
                .right(new Integer[]{loginInfo.getAccount().getId()})
                .build());
        params = mapper.writeValueAsString(paramsList);

        return pubMsgApi.page(isPage, page, limit, params, ordersParams);
    }

    /**
     * 统计当前账户的未读消息数量
     *
     * @return RepBody<Integer>
     */
    @GetMapping("/count/no-read")
//    @ApiLogAnnotation(name = "PubMsg:countNoRead")
    public RepBody<Integer> countNoRead(HttpServletRequest request) {
        LoginInfo loginInfo = getLoginInfo(request);
        if (null == loginInfo) {
            return ok(0);
        }

        return ok(pubMsgExtendRepo.countAllByRecvUserIdAndReadTimeIsNull(loginInfo.getAccount().getId()));
    }

    /**
     * 创建部门通知
     *
     * @param request 请求体
     * @param dept    通知部门
     * @param content 消息内容
     * @return RepBody<Integer>
     */
    @PostMapping("/create-dept-notify/{dept}")
    @ApiLogAnnotation(name = "PubMsg:createDeptNotify")
    public RepBody<List<PubMsg>> createDeptNotify(HttpServletRequest request,
                                                  @PathVariable("dept") Integer dept,
                                                  @RequestParam(value = "dataId", required = false, defaultValue = "0") String dataId,
                                                  @RequestBody @Validated String content) throws Exception {
        LoginInfo loginInfo = getLoginInfo(request);
        if (null == loginInfo) {
            return error(RepCodeEnum.ERR_LOGIN_EXPIRE);
        }

        List<PubMsgForm> msgForms = new LinkedList<>();

        List<PubAccount> accounts = pubAccountRepo.findAllByDept(dept);
        accounts.forEach(account -> {
            // 创建接收人的通知消息
            msgForms.add(PubMsgForm.builder()
                    .userId(loginInfo.getAccount().getId())
                    .recvUserId(account.getId())
                    .type(1)
                    .targetId(dataId)
                    .content(content)
                    .build());
        });

        return pubMsgApi.creates(msgForms);
    }
}